#include "Enemy.h"
#include "../SGD Wrappers/SGD_GraphicsManager.h"
#include "GamePlayState.h"
#include "../SGD Wrappers/SGD_InputManager.h"
#include <sstream>
#include "../SGD Wrappers/SGD_Event.h"
#include "Player.h"
#include "ParticleManager.h"
#include "Game.h"
#include "Physics.h"
#include "DestroyEntityMessage.h"
#include "../SGD Wrappers/SGD_Event.h"
#include "animation.h"

AISM Enemy::machine;

Enemy::Enemy(Entity* target) : Listener(this)
{
	RegisterForEvent("PLANETCOLLIDE");
	RegisterForEvent("SHADOWHOOK");
	player = target;
	player->AddRef();
	machine.SetTarget((Player*)target);
	spike = "spike";
	image = SGD::GraphicsManager::GetInstance()->LoadTexture("resources/images/enemy.png");
	Tentacleimage = SGD::GraphicsManager::GetInstance()->LoadTexture("resources/images/boss/RTtentacle.png");
	shabunImage = new animation;
	shabunImage->image = SGD::GraphicsManager::GetInstance()->LoadTexture("resources/images/Shabun.png", {255,255,255,255});
	shabunImage->initPos = { 0, 0 };
	shabunImage->cellSize = { 32, 32 };
	shabunImage->currCellCol = 0;
	shabunImage->currCellRow = 4;
	shabunImage->timePerFrame = .2f;

	shaflackImage = new animation;
	shaflackImage->image = SGD::GraphicsManager::GetInstance()->LoadTexture("resources/images/Shaflak.png", { 255, 255, 255, 255 });
	shaflackImage->initPos = { 0, 10 };
	shaflackImage->cellSize = { 64, 64 };
	shaflackImage->currCellCol = 0;
	shaflackImage->currCellRow = 0;
	shaflackImage->timePerFrame = .2f;

}

Enemy::~Enemy()
{
	SGD::GraphicsManager::GetInstance()->UnloadTexture(image);
	SGD::GraphicsManager::GetInstance()->UnloadTexture(Tentacleimage);
	SGD::GraphicsManager::GetInstance()->UnloadTexture(shabunImage->image);
	delete shabunImage;
	SGD::GraphicsManager::GetInstance()->UnloadTexture(shaflackImage->image);
	delete shaflackImage;
	if (player)
		player->Release();
	if (semitterID)
		ParticleManager::GetInstance()->FreeEmitter(semitterID);
}

void Enemy::Update(float elapsedTime)
{
	SGD::Rectangle camOffset{ { Game::GetInstance()->GetCameraPos().x - 100,
		Game::GetInstance()->GetCameraPos().y - 100 },
		SGD::Size{ (Game::GetInstance()->GetScreenWidth() + 500) / Game::GetInstance()->GetZoomLevel(),
		(Game::GetInstance()->GetScreenHeight() + 500) / Game::GetInstance()->GetZoomLevel() } };
	SGD::Rectangle posRect = { this->GetRect().ComputeCenter(), SGD::Size{ 1, 1 } };
	if (camOffset.IsIntersecting(posRect))

	{
		collisionFlag = 0;
		fireTimer -= elapsedTime;
	if (currentPlanet != nullptr)
	{
		SGD::Vector Rotationangle = currentPlanet->GetRect().ComputeCenter() - GetRect().ComputeCenter();
		Rotationangle.Normalize();
		rotation = acosf(Rotationangle.y);
		if (Rotationangle.x > 0)
			rotation = -rotation;
	}
	if (GetEType() == shabun || GetEType() == shadisc)
	{
		shabunImage->timeWaited += elapsedTime;
		if (!GetFacingLeft())
			shabunImage->currCellRow = 4;
		if (GetFacingLeft())
			shabunImage->currCellRow = 5;
		if (shabunImage->timeWaited >= shabunImage->timePerFrame)
		{
			shabunImage->timeWaited = 0;
			shabunImage->currCellCol++;

				if (shabunImage->currCellCol > 2)
					shabunImage->currCellCol = 0;
			
		}
	}
	if (GetEType() == shaflak)
	{
		shaflackImage->timeWaited += elapsedTime;
		if (!GetFacingLeft())
			shaflackImage->currCellRow = 1;
		if (GetFacingLeft())
			shaflackImage->currCellRow = 0;
		if (shaflackImage->timeWaited >= shaflackImage->timePerFrame)
		{
			shaflackImage->timeWaited = 0;
			shaflackImage->currCellCol++;

			if (shaflackImage->currCellCol > 2)
				shaflackImage->currCellCol = 0;

		}
	}

		Aggro();
		machine.update(*this, elapsedTime);
		Entity::Update(elapsedTime);
		/*if (spiked && !semitterID)
		{
			semitterID = ParticleManager::GetInstance()->CreateEmitter(spike.c_str(), this);
		}
		if (!spiked && semitterID)
		{
			ParticleManager::GetInstance()->FreeEmitter(semitterID);
			semitterID = 0;
		}*/
	}
	else
		collisionFlag = -1;
}

void Enemy::Render()
{
	SGD::Rectangle rect;
	rect = { position.x - range - Game::GetInstance()->GetCameraPos().x, position.y - range - Game::GetInstance()->GetCameraPos().y,
		position.x + range - Game::GetInstance()->GetCameraPos().x, position.y + range - Game::GetInstance()->GetCameraPos().y };
	//SGD::GraphicsManager::GetInstance()->DrawRectangle(
	//	rect, SGD::Color{ 80, 255, 255, 0 }); 
	rect = { SGD::Point{ position.x - Game::GetInstance()->GetCameraPos().x,
		position.y - Game::GetInstance()->GetCameraPos().y }, size };
	//SGD::GraphicsManager::GetInstance()->DrawRectangle(
	//	rect, SGD::Color{ 255, 0, 0 });

	SGD::Rectangle camOffset{ { Game::GetInstance()->GetCameraPos().x - 100,
		Game::GetInstance()->GetCameraPos().y - 100 },
		SGD::Size{ (Game::GetInstance()->GetScreenWidth() + 500) / Game::GetInstance()->GetZoomLevel(),
		(Game::GetInstance()->GetScreenHeight() + 500) / Game::GetInstance()->GetZoomLevel() } };
	SGD::Rectangle posRect = { this->GetRect().ComputeCenter(), SGD::Size{ 1, 1 } };
	if (camOffset.IsIntersecting(posRect))
	{
		SGD::GraphicsManager* graphics = SGD::GraphicsManager::GetInstance();

		SGD::Rectangle rect = { SGD::Point{ position.x - Game::GetInstance()->GetCameraPos().x,
			position.y - Game::GetInstance()->GetCameraPos().y }, size };

		SGD::Point renderPos{ (position.x - Game::GetInstance()->GetCameraPos().x) * Game::GetInstance()->GetZoomLevel(),
			(position.y - Game::GetInstance()->GetCameraPos().y) * Game::GetInstance()->GetZoomLevel() };

		if (GetEType() == shatent)
		{
			graphics->DrawTexture(Tentacleimage, renderPos, rotation, GetSize() / 2, {},
				(SGD::Size{ Game::GetInstance()->GetZoomLevel(), Game::GetInstance()->GetZoomLevel() }));
		}
		else if (GetEType() == shabun)
		{
			
			shabunImage->Render(renderPos, rotation, 5, Game::GetInstance()->GetZoomLevel());
		}
		else if (GetEType() == shadisc)
		{
			shabunImage->Render(renderPos, rotation, 5, Game::GetInstance()->GetZoomLevel(),51,255,100);

		}
		else if (GetEType() == shaflak)
		{
			if (flipped)
				shaflackImage->Render(renderPos, rotation + 180, 5, Game::GetInstance()->GetZoomLevel() * .5f);
			else
				shaflackImage->Render(renderPos, rotation, 5, Game::GetInstance()->GetZoomLevel() * .5f);
		}
		else
		{
			graphics->DrawTexture(image, renderPos, rotation, GetSize() / 2, {},
				(SGD::Size{ Game::GetInstance()->GetZoomLevel(), Game::GetInstance()->GetZoomLevel() }));
		}
		
	}
	
}

void Enemy::HandleCollision(const IEntity* other)
{
	if (other->GetType() == ENT_PLANET && currentPlanet == nullptr)
	{
		const Planets* p = dynamic_cast<const Planets*>(other);
		currentPlanet = const_cast<Planets *>(p);
		state = State::move;
	}
	if (other->GetType() == ENT_PLAYER && currentPlanet == nullptr)
	{
		SGD::Event em = { "PARTICLE_DAMAGE" };
		em.SendEventNow(nullptr);
		DestroyEntityMessage* msg = new DestroyEntityMessage(this);
		msg->QueueMessage();
		msg = nullptr;
	}
}

void Enemy::Aggro()
{
	SGD::Vector dist = player->GetRect().ComputeCenter() - GetRect().ComputeCenter();
	if (range >= dist.ComputeLength())
	{
		inRange = true;
	}
	else
		inRange = false;
}
void Enemy::HandleEvent(const SGD::Event* pEvent)
{
	if (pEvent->GetEventID() == "PLANETCOLLIDE" && type == shaflak && dynamic_cast<Player*>(player)->GetCurrentPlanet()==currentPlanet)
	{
		SGD::Vector*pvel = (SGD::Vector*)pEvent->GetData();
		*pvel *= player->GetMass();
		float pmom = pvel->ComputeLength();
		if (pmom >= 4000)
		{
			flipped = true;
		}
	}
	if (pEvent->GetEventID() == "SHADOWHOOK" && (type == shike || type == shadisc) && pEvent->GetSender() == player)
	{
		hookPos = *((SGD::Point*)pEvent->GetData());
	}
}